package CapaLogica;

import org.apache.log4j.Logger;
import CapaDatos.*;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.logging.Level;
import javax.swing.JOptionPane;
import CapaPersistencia.ControladorCliente;
import CapaPersistencia.ControladorReserva;
import ve.edu.ucab.server.logica.LogicaServidor;

/**
 *
 * @author Cisco
 */
public class GestionResort implements LogicaServidor {
    private int cont;
      /** variable que lleva los ID**/
    private static int arrayId []=new int [500];
        /** atributo de tipo ListaCliente**/
    private static ListaCliente losClientes= new ListaCliente();
        /** atributo de tipo ListaHabitacion**/
    private static ListaHabitacion lasHabitaciones = new ListaHabitacion();
       /** atributo de tipo ListaReserva**/
    private static ListaReserva lasReservas= new ListaReserva();
       /** atributo de tipo ListaInvitado**/
    private static ListaInvitado losInvitados = new ListaInvitado();
       /** atributo de tipo ListaNomina**/
    private static ListaNomina lasNominas = new ListaNomina();
      /** atributo de tipo ListaRestaurante**/
    private static ListaRestaurante losRestaurantes = new ListaRestaurante();
       /** atributo de tipo ControladorCliente**/
    private ControladorCliente control = new ControladorCliente();
       /** atributo de tipo ControladorReserva**/
    private ControladorReserva controlR = new ControladorReserva();
      /** atributo de tipo ComunicaPago**/
    private   ComunicaPago comunicameAPago = new ComunicaPago();
      /** atributo de tipo Logger**/
    private  Logger bitacora = Logger.getLogger(getClass());

        /**
     * @return the losClientes
     */
    public static ListaRestaurante getLosRestaurantes() {
        return losRestaurantes;
    }

    public static void setLosRestaurantes(ListaRestaurante losRestaurantes) {
        GestionResort.losRestaurantes = losRestaurantes;
    }


    /**
     * @return the losClientes
     */
    public static ListaCliente getLosClientes() {
        return losClientes;
    }
    /**
     * @return the lasHabitaciones
     */
    public static ListaHabitacion getLasHabitaciones() {
        return lasHabitaciones;
    }
    /**
     * @return the lasNominas
     */
    public static ListaNomina getLasNominas() {
        return lasNominas;
    }
    /**
     * @return the lasReservas
     */
    public static ListaReserva getLasReservas() {
        return lasReservas;
    }
    /**
     * @return the losInvitados
     */
    public static ListaInvitado getLosInvitados() {
        return losInvitados;
    }
    /**
    * firma para realizar los casos de uso dependiendo de cual se presente
    * por medio de la libreria JSockets
    * @param arg el caso de uso a trabajar, mas los parametros de dicho caso
    * @return string, dependiendo del caso:
    *
    * de ser el caso 1, el poder acceder al sistema
    * se retorna true mas los datos del cliente, de no poder
    * acceder al sistema se retorna false
    *
    * de estar en el caso 2, el realizar un reserva, se retorna true si se pude
    * realizar la reserva mas los datos de la misma, si no se pudo realizar
    * la reserva se retorna false
    *
    * de estar en el caso 3, registrar un usuario, se retorna true si se pudo
    * registrar al cliente y false si no se pudo registrar
    *
    * de estar en el caso 4, el consultar una reserva, ser retorna los datos
    * de la reserva de existir y de no existir se retorna cinco "null"
    *
    * de estar en el caso 5, añadir un acompañante a la reserva, se retorna
    * true si se pudo resgistrar y false si no se pudo registrar el acompañante
    *
    * y  de estar en el caso 6, calcular el monto de la reserva, se retorna
    * true mas el monto de la reserva, de no poder calcular el monto se retorna
    * false
    */
     public String realizarOperacion(String arg) {
        String[] subArg = arg.split(":");
        int indicaPosicion=Integer.parseInt(subArg[0]);

        switch(indicaPosicion)
            {

            case 1:  AccesoSistema elAcceso= new AccesoSistema(subArg[1],subArg[2]);
                     String indicador="false";
                     indicador=elAcceso.validarExistenciaCliente(losClientes, subArg[1],subArg[2]);
                       if(indicador.equals("false") == false )
                       {
                       Cliente clienteLogin = losClientes.BuscarCliente(indicador);
                       return "true"+":"+clienteLogin.getNombre()+":"+clienteLogin.getApellido()+":"+clienteLogin.getCedula()+":"+clienteLogin.getSexo()+":"+clienteLogin.getFechaNac()+":"+clienteLogin.getEdoCivil()+":"+clienteLogin.getNacionalidad();
                       }
                   else
                     return "false";

            case 2:  //Registrar una nueva reserva
                 int i=0;
                 boolean seReserva = false;
                 Date hoy = null, inicio = null,fin = null;
                 String fechaActual = subArg[3];
                 String DateFormat = "dd/MM/yyyy";
                SimpleDateFormat sdf = new SimpleDateFormat(DateFormat);
                try {
                    hoy = sdf.parse(fechaActual);
                    inicio = sdf.parse(subArg[1]);
                    fin = sdf.parse(subArg[2]);
                } catch (ParseException ex) {
                    java.util.logging.Logger.getLogger(GestionResort.class.getName()).log(Level.SEVERE, null, ex);
                }

                if(inicio.before(hoy) || fin.before(hoy) || fin.before(inicio))
                    return "false"+":"+"Alguna de las fechas no es correcta. Intente de nuevo";

                else{

                    while (arrayId[i]!=0)
                      {
                        cont++;
                        i++;
                      }

                String cedulaCliente = subArg[5];
                Cliente cliente = losClientes.BuscarCliente(cedulaCliente);
                Reserva laReserva= new Reserva(cliente, subArg[1], subArg[2]);
                Habitacion laHabitacionRes = lasReservas.buscarHabitacionDeReserva(subArg[4]);

                if(laHabitacionRes == null && laReserva != null)
                {
                    Habitacion habitacion = lasHabitaciones.BuscarHabitacion(subArg[4]);
                    if(habitacion != null)
                if(habitacion.getEdoActual().equalsIgnoreCase("Habilitada"))
                {

                      laReserva.setLaHabitacion(habitacion);
                      laReserva.generarId(cont,arrayId);
                      lasReservas.agregarElemento(laReserva);
                      losClientes.BuscarCliente(cedulaCliente).setNumReservas(cliente.getNumReservas() + 1);
                      losClientes.BuscarCliente(cedulaCliente).esClienteEstrella(cliente);
                      Cliente miCliente = losClientes.BuscarCliente(cedulaCliente);
                      control.actualizarCliente(miCliente.getCedula(),miCliente.getNombre(), miCliente.getApellido(), miCliente.getSexo(), miCliente.getNacionalidad(), miCliente.getEdoCivil(), miCliente.getUserName(), miCliente.getPassword(), miCliente.getFechaNac(),miCliente.getNumReservas(),miCliente.getTipoCliente());
                      controlR.actualizarReserva(miCliente.getCedula(),laReserva.getLaHabitacion().getID(), laReserva.getFechaInicio(), laReserva.getFechaFin(), laReserva.getID(), laReserva.getMonto());

                      return "true"+":"+laReserva.getID();
                }
                else
                    return "false"+":"+"Lo sentimos pero la habitacion solicitada no se encuentra habilitada en estos momentos";
                }
                else
                 if (laHabitacionRes != null &&  laReserva!= null )
                  {
                        if(laHabitacionRes.getEdoActual().equalsIgnoreCase("Dañada")== false || laHabitacionRes.getEdoActual().equalsIgnoreCase("En reparacion")== false)
                        {
                            try {
                                seReserva = lasReservas.esFechaValida(subArg[4], subArg[1], subArg[2]);
                            } catch (ParseException ex) {
                                    java.util.logging.Logger.getLogger(GestionResort.class.getName()).log(Level.SEVERE, null, ex);
                            }

                 if(seReserva)
                 {
                    laReserva.setLaHabitacion(laHabitacionRes);
                    laReserva.generarId(cont,arrayId);
                    lasReservas.agregarElemento(laReserva);
                    losClientes.BuscarCliente(cedulaCliente).setNumReservas(cliente.getNumReservas() + 1);
                    losClientes.BuscarCliente(cedulaCliente).esClienteEstrella(cliente);
                    Cliente miCliente = losClientes.BuscarCliente(cedulaCliente);
                    control.actualizarCliente(miCliente.getCedula(),miCliente.getNombre(), miCliente.getApellido(), miCliente.getSexo(), miCliente.getNacionalidad(), miCliente.getEdoCivil(), miCliente.getUserName(), miCliente.getPassword(), miCliente.getFechaNac(),miCliente.getNumReservas(),miCliente.getTipoCliente());
                    controlR.actualizarReserva(miCliente.getCedula(),laReserva.getLaHabitacion().getID(), laReserva.getFechaInicio(), laReserva.getFechaFin(), laReserva.getID(), laReserva.getMonto());
                    return "true"+":"+laReserva.getID();
                 }
                 else if(!seReserva) //la fecha que solicita el usuario esta en el intervalo de fechas de alguna reserva ya hecha con esa habitacion
                        return "false"+":"+"Disculpe, la habitación se encuentra ocupada para este rango de fechas.\nPor favor intente de nuevo";
                        }
                         else  //la habitacion no esta disponible, debe estar o en reparacion o dañada
                           return "false"+":"+"Lo sentimos pero la habitacion solicitada no se encuentra habilitada en estos momentos";
                }
            else //la reserva es null o la habitacion, y se procede a negar el registro de la reserva
                 return "false"+":"+"Error la reserva no ha sido efectuada";
                }

            case 3 : //Registrar un nuevo usuario
                ComunicaCliente comunicameACliente = new ComunicaCliente();
                Boolean seRegistro = false;

                     Cliente elCliente= new Cliente(  subArg[1] //Nombre
                                                     ,subArg[2] //Apellido
                                                     ,subArg[3] //Cedula
                                                     ,subArg[9] //Nacionalidad
                                                     ,subArg[4] //sexo
                                                     ,subArg[5] //fechaNac
                                                     ,subArg[6] //edoCivil
                                                     ,subArg[8] //Password
                                                     ,subArg[7]); //userName

                     if(elCliente != null)
                     {
                        elCliente.setTipoCliente(comunicameACliente.enviarTipoCliente(elCliente.getFechaNac()));
                        seRegistro=losClientes.agregarElemento(elCliente);
                        if(seRegistro==true){
                            control.nuevoCliente(subArg[3], subArg[1], subArg[2], subArg[4], subArg[9], subArg[6], subArg[7], subArg[8], subArg[5]); // Inserta el nuevo cliente en el archivo desde la aplicacion cliente.
                            return "true";
                        }
                        else
                            return "false";
                     }
                     else return "false";


           case 4: //Consultar una nueva reserva
                    Reserva lareserva = new Reserva();
                    lareserva = lasReservas.BuscarReserva(subArg[1],Integer.parseInt(subArg[2]));
                    if(lareserva!= null)
                    {
                          if (lasReservas.BuscarReserva(Integer.parseInt(subArg[2])).getLosInvitados()!= null )
                          {
                        return (String.valueOf(lareserva.getID())+":"+lareserva.getFechaInicio()+":"+lareserva.getFechaFin()+":"+lareserva.getLaHabitacion().getID()+":"+String.valueOf(lasReservas.BuscarReserva(Integer.parseInt(subArg[2])).getLosInvitados().contarElementos(subArg[2])));
                          }
                        else
                         return (String.valueOf(lareserva.getID())+":"+lareserva.getFechaInicio()+":"+lareserva.getFechaFin()+":"+lareserva.getLaHabitacion().getID()+":"+"null");
                    }
                    else
                        return "null:"+"null:"+"null:"+"null:"+"null";

            case 5: //Agregar un invitado
                    Invitado elInvitado = new Invitado(subArg[3],subArg[4],subArg[5],subArg[6],subArg[7]);
                    Reserva miReserva = lasReservas.BuscarReserva(subArg[1],Integer.parseInt(subArg[2]));
                    elInvitado.setIdReserva(Integer.parseInt(subArg[2]));

                    if(elInvitado != null && miReserva != null)
                    {
                    double montoInvitado = comunicameAPago.calcularMontoInvitado(elInvitado, miReserva.getFechaInicio(),miReserva.getFechaFin());
                    losInvitados.agregarElemento(elInvitado);
                    lasReservas.BuscarReserva(subArg[1],Integer.parseInt(subArg[2])).setLosInvitados(losInvitados);
                    lasReservas.BuscarReserva(subArg[1],Integer.parseInt(subArg[2])).setMonto(montoInvitado + miReserva.getMonto());
                    return "true";
                    }
                    else return "false"; //falta el mensaje


            case 6: //Generar monto reserva

               Cliente cliente2 = losClientes.BuscarCliente(subArg[1]);
               Reserva reservaAux = lasReservas.BuscarReserva(subArg[1],Integer.parseInt(subArg[2]));
               if (reservaAux != null)
               {

               Double Monto = reservaAux.getMonto() + comunicameAPago.calcularMonto(cliente2,reservaAux.getFechaInicio(),reservaAux.getFechaFin());
               controlR.actualizarReserva(cliente2.getCedula(), reservaAux.getLaHabitacion().getID(), reservaAux.getFechaInicio(), reservaAux.getFechaFin(), reservaAux.getID(), Monto);
               return "true"+":"+Monto.toString();
               }
               else
                   return "false"+":"+"No se puede calcular el monto porque la reserva no fue generada";

        default:
                 bitacora.info("Caso de uso no existente");
                 bitacora.error("error");

            }

return "";
    }


}